home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / umich / network / ka9q / nhclb120.zoo / mac_at.c < prev    next >
C/C++ Source or Header  |  1992-02-11  |  13KB  |  571 lines

  1. /*
  2.  * This file contains the code for using the AppleTalk network.  This is a 
  3.  * first cut and hopefully it will work.
  4.  */
  5.  
  6.  
  7. #include <stdio.h>
  8. #include "global.h"
  9. #include "mbuf.h"
  10. #include "iface.h"
  11. #include "timer.h"
  12. #include "ip.h"
  13. #include "arp.h"
  14. #include <MacTypes.h>
  15. #include <Appletalk.h>
  16. #include "mac_AT.h"
  17. #include "trace.h"
  18.  
  19. struct at at[AT_MAX];        /* Per-controller info */
  20.  
  21. char appletalk_bdcst = 0xff;
  22.  
  23. unsigned    nat = 0;
  24.     
  25. /* Initialize interface */
  26. at_init(interface,bufsize)
  27. struct interface *interface;
  28. unsigned bufsize;    /* Maximum size of receive queue in PACKETS */
  29. {
  30.     register struct at *atp;
  31.     int16 dev;
  32.     char *malloc();
  33.     int err;
  34.     ABRecPtr abrrdptr;
  35.     ABRecPtr abrwrptr;
  36.     int node, net;        /* vars to hold my node id and net id */
  37.     
  38. #ifdef DEBUG
  39.     printf("at_init called\n");
  40. #endif
  41.     dev = interface->dev;
  42.     if ( dev >= nat )
  43.     {
  44.         printf("problem with dev entry.  Number is  %d, max = %d\n", dev,nat);
  45.         return(-1);
  46.     }
  47.     atp = &at[dev];
  48.     atp->rcvmax = bufsize;
  49.     /*
  50.      * see if the device is available for use with AppleTalk
  51.      */
  52.     err = MPPOpen();
  53.     if ( err != noErr )
  54.     {
  55.         printf("AppleTalk is not available on device  error %d\n", err);
  56.         return(-1);
  57.     }
  58.  
  59.     /*
  60.      * See if we can put our protocol type in and have the default handler use it
  61.      */
  62.     err = LAPOpenProtocol(atp->ProtoType, NULL);
  63.     if ( err != noErr)
  64.     {
  65.         /*
  66.          * In case we bombed out last time, try and remove the protocol type and try again
  67.          */
  68.         if ( LAPCloseProtocol(atp->ProtoType) != 0 )
  69.         {
  70.  
  71.             printf("Could not initialize AppleTalk with protocol type %d, error %d\n",
  72.                  atp->ProtoType, err);
  73.             return(-1);
  74.         }
  75.         err = LAPOpenProtocol(atp->ProtoType, NULL);
  76.         if ( err != noErr)
  77.         {
  78.             printf("Could not initialize AppleTalk with protocol type %d, error %d\n",
  79.                  atp->ProtoType, err);
  80.             return(-1);
  81.         }
  82.     }
  83.     /*
  84.      * Since everything is alright, lets allocate an ABusRecord
  85.      */
  86.     
  87.     atp->rdATptr = NewHandle(lapSize);
  88.     if ( atp->rdATptr == NULL)
  89.     {
  90.         printf("Could not allocate handel for AppleBuss (0).\n");
  91.         (void)LAPCloseProtocol(atp->ProtoType);
  92.         return(-1);
  93.     }
  94.  
  95.     atp->wrATptr = NewHandle(lapSize);
  96.     
  97.     if ( atp->wrATptr == NULL)
  98.     {
  99.         printf("Could not allocate handel for AppleBuss (1).\n");
  100.         DisposHandle(atp->rdATptr);
  101.         (void)LAPCloseProtocol(atp->ProtoType);
  102.         return(-1);
  103.     }
  104.     
  105.     /*
  106.      * now that everything is going well, let's issue an async read on the protocol
  107.      */
  108.     HLock(atp->rdATptr);
  109.     HLock(atp->wrATptr);
  110.     abrrdptr = *atp->rdATptr;
  111.     abrwrptr = *atp->wrATptr;
  112.     
  113.     abrwrptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  114.     if ( at_startread(atp, abrrdptr) != 0 )
  115.     {
  116.         printf("Could not perform read on AppleTalk network.  Closing down device.\n");
  117.         return(-1);
  118.     }
  119.     
  120.     if ( GetNodeAddress( &node, &net) != 0)
  121.     {
  122.         printf("Could not get my own node address.  Something is wrong!!\n");
  123.         return(-1);
  124.     }
  125.     if ( interface->hwaddr == NULLCHAR )
  126.     {
  127.         if ( (interface -> hwaddr = malloc(4)) == NULLCHAR)
  128.         {
  129.             printf("Could not allocate memory for hardware address.\n");
  130.             return(-1);
  131.         }
  132.     }
  133.         
  134.     *interface->hwaddr = (unsigned char) node;
  135.     printf("My AppleTalk node number is %d\n", node);
  136.     return(0);
  137. }
  138.  
  139. /* Send an IP datagram on AppleTalk */
  140. at_send(bp,interface,gateway,precedence,delay,throughput,reliability)
  141. struct mbuf *bp;        /* Buffer to send */
  142. struct interface *interface;    /* Pointer to interface control block */
  143. int32 gateway;            /* IP address of next hop */
  144. char precedence;
  145. char delay;
  146. char throughput;
  147. char reliability;
  148. {
  149.     char *egate,*res_arp();
  150.     egate = res_arp(interface,ARP_APPLETALK,gateway,bp);
  151.     if(egate != NULLCHAR)
  152.     {
  153.         (*interface->output)(interface,egate,interface->hwaddr,AIP_TYPE,bp);
  154.     }
  155. }
  156.  
  157. /* Send a packet with Ethernet header */
  158. at_output(interface,dest,source,type,bp)
  159. struct interface *interface;        /* Pointer to interface control block */
  160. char dest[];        /* Destination Ethernet address */
  161. char source[];        /* Source Appletalk address */
  162. int16 type;        /* Type field */
  163. struct mbuf *bp;    /* Data field */
  164. {
  165.     struct    appletalk ap;    /* AppleTalk struct for header info. */
  166.     struct    mbuf    *hdr;
  167.     struct    mbuf    *htonat();
  168.  
  169.     memcpy(&ap.source, source, APPLE_LEN);
  170.     memcpy(&ap.dest, dest, APPLE_LEN);
  171.     ap.type = type;
  172.     hdr = htonat(&ap);
  173.     hdr->next = bp;
  174.     (*interface->raw)(interface,hdr);
  175. }
  176.  
  177. /* Send raw packet (caller provides header) */
  178. at_raw(interface,bp)
  179. struct interface *interface;        /* Pointer to interface control block */
  180. struct mbuf *bp;    /* Data field */
  181. {
  182.     register struct at *atp;    /* AppleTalk pointer */
  183.     short size;                    /* size of data in mbuf */
  184.     int err;                    /* error indicator from mac stuff */
  185.     short    tmp=2;                /* there is an offset of 2 in the data buffer */
  186.     short *mptr;                /* temporary pointer */
  187.     ABRecPtr abrwrptr;            /* pointer to applebuss record */
  188.     struct appletalk ap;        /* appletalk struct for front of record */
  189.     struct mbuf    *hdr;            /* extra mbuf pointer */
  190.     
  191.     atp = &at[interface->dev];
  192.     if ( interface->dev >= nat )
  193.     {
  194.         printf("problem with dev entry.  Number is  %d, max = %d\n", interface->dev,nat);
  195.         return(-1);
  196.     }
  197.     dump(interface,IF_TRACE_OUT,TRACE_APPLETALK,bp);
  198.     size = len_mbuf(bp);
  199.     
  200.     /*
  201.         Set up the transmit structure
  202.      */
  203.     
  204.     /*
  205.      * take a part to get the address
  206.      */
  207.     ntohat(&ap, &bp);
  208.     abrwrptr = *atp->wrATptr;
  209.     abrwrptr->lapProto.lapAddress.dstNodeID = ap.dest;
  210.     abrwrptr->lapProto.lapDataPtr = atp->buffer;
  211.     abrwrptr->lapProto.lapAddress.lapProtType = atp->ProtoType;
  212.     
  213.     /*
  214.      * now put header back on
  215.      */
  216.      
  217.     hdr = htonat(&ap);
  218.     hdr->next = bp;
  219.  
  220.     /*
  221.         Copy all the data from the mbuf to the data packet holder.
  222.         Max amount of data is 600 bytes
  223.      */
  224.     while  ( hdr != NULLBUF)
  225.     {
  226.         bcopy(hdr->data, &abrwrptr->lapProto.lapDataPtr[tmp], hdr->cnt);
  227.         tmp += hdr->cnt;
  228.         if ( tmp >= 600)
  229.             printf("sending: ERROR IN PACKET SIZE, size = %d\n", tmp);
  230.  
  231.         hdr = free_mbuf(hdr);
  232.     }
  233.  
  234.     /* 
  235.         set the packet length in the first two bytes of the LAP data buffer
  236.         including these two bytes.
  237.      */
  238.      
  239.     mptr = abrwrptr->lapProto.lapDataPtr;
  240.     *mptr = tmp;
  241.     
  242.     abrwrptr->lapProto.lapReqCount = tmp;
  243.     
  244.     atp->astats.out++;
  245.     
  246.     /* send off a sync write and wait for return value. */
  247.     
  248.     err = LAPWrite(atp->wrATptr, FALSE);
  249.     
  250.     if ( err != noErr )
  251.     {
  252.         printf("at_raw: write failure to AppleTalk (%d)\n", err);
  253.         return(0);
  254.     }
  255. }
  256.  
  257. /* Process any incoming AppleTalk packets on the receive queue */
  258. int
  259. at_recv(interface)
  260. struct interface *interface;
  261. {
  262.     struct at *atp;            /* appletalk pointer */
  263.     struct mbuf *bp;        /* place to store all the buffers */
  264.     ABRecPtr abrrdptr;        /* Appletalk network storage */
  265.     int    err;
  266.     extern int32 ip_addr;
  267.     struct appletalk ap;
  268.     struct mbuf *htonat();
  269.     
  270.     /*
  271.      *  just to make sure it is for us
  272.      */
  273.  
  274.     atp = &at[interface->dev];
  275.     
  276.     if ( interface->dev >= nat )
  277.     {
  278.         printf("problem with dev entry.  Number is  %d, max = %d\n", interface->dev,nat);
  279.         return(-1);
  280.     }
  281.     
  282.     /*
  283.      * get a pointer to the read structure
  284.      */
  285.     
  286.     abrrdptr = *atp->rdATptr;
  287.     
  288.     /*
  289.      * since this was an async read, a 1 indicates it has not completed yet.
  290.      */
  291.  
  292.     if ( abrrdptr->lapProto.abResult == 1)
  293.     {
  294.         return;
  295.     }
  296.     else if  ( abrrdptr->lapProto.abResult == buf2SmallErr)
  297.     {
  298.         atp->astats.badsize++;
  299.         if ( at_startread(atp, abrrdptr ) != 0)
  300.         {
  301.             printf("Error in starting async read on appletalk network.\n");
  302.         }
  303.         return(-1);
  304.     }
  305.     else if  ( abrrdptr->lapProto.abResult == readQErr)
  306.     {
  307.         atp->astats.drop++;
  308.         if ( at_startread(atp, abrrdptr ) != 0)
  309.         {
  310.             printf("Error in starting async read on appletalk network.\n");
  311.         }
  312.         return(-1);
  313.     }
  314.     
  315.     /*
  316.      * now set up the mbuf. count -2 because AT puts in the count sent in the first two]
  317.      * bytes of the data.
  318.      */
  319.     
  320.     if((bp = alloc_mbuf(abrrdptr->lapProto.lapActCount-2)) == NULLBUF)
  321.     {
  322.         atp->astats.nomem++;
  323.         if ( at_startread(atp, abrrdptr ) != 0)
  324.         {
  325.             printf("Error in starting async read on appletalk network.\n");
  326.         }
  327.         return(-1);
  328.     }
  329.     
  330.     /*
  331.      * move it over
  332.      */
  333.  
  334.     bcopy(&abrrdptr->lapProto.lapDataPtr[2], bp->data, abrrdptr->lapProto.lapActCount-2);
  335.     
  336.     bp->cnt = abrrdptr->lapProto.lapActCount - 2;
  337.     
  338.     /* not start another async read on this device. */
  339.         
  340.     if ( at_startread(at, abrrdptr) != 0 )
  341.     {
  342.         printf("Could not perform read on AppleTalk network.  Closing down device.\n");
  343.         return(-1);
  344.     }
  345.     ntohat(&ap, &bp);
  346.     
  347.     switch (ap.type)
  348.     {
  349.     
  350.         case AARP_TYPE:
  351.             arp_input(interface, bp);